 
<template>
  <el-form ref="form" v-bind="$attrs" :model="formData" v-on="$listeners" label-width="80px" @validate="validateFields">
    <el-row v-for="(element,index) in fieldsMap" :key="index+'-'+element.length">
      <el-col v-for="item in element" :key="item.prop" v-bind="item">
        <el-form-item v-bind="item">
          <el-select v-if="['select'].includes(item.type)" clearable v-bind="item" v-model="formData[item.prop]">
            <el-option v-for="k in item.option" :key="k.label" :label="k.label" :value="k.value"></el-option>
          </el-select>
          <el-input v-else-if="['text','number',undefined].includes(item.type)" clearable v-bind="item" v-model="formData[item.prop]"></el-input>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>
<script>
export default {
  name: "mixform",
  data() {
    return {
      formData: {},
      fieldsMap: []
    };
  },
  props: {
    value: {
      type: Object,
      required: true
    },
    fields: {
      type: Array,
      required: true
    }
  },
  watch: {
    fields: {
      deep: true,
      immediate: true,
      handler(a) {
        this.initFields([...a]);
      }
    },
    value: {
      immediate: true,
      handler(a) {
        this.formData = a;
      }
    },
    formData: {
      deep: true,
      handler(a) {
        this.$emit("input", a);
      }
    }
  },
  methods: {
    async validate() {
      return this.$refs["form"].validate();
    },
    async resetFields() {
      return this.$refs["form"].resetFields();
    },
    validateFields(...val) {
      this.$emit("validate", val);
    },
    async initFields(fields) {
      let newFields = [];
      let index = 0;
      newFields[index] = [];
      for (let i = 0; i < fields.length; i++) {
        const item = fields[i];
        if (item?.options instanceof Function) {
          item.option = await item.options();
        }
        if (item?.wrap) {
          index++;
          newFields[index] = [];
        }
        if (item?.option) {
          item.option = item.option.map((e) => {
            return { label: this.getField(item, e, "label"), value: this.getField(item, e, "value") };
          });
          console.log(item);
        }
        newFields[index].push(item);
      }
      this.fieldsMap = [...newFields];
    },
    getField(item, k, type) {
      if (item?.config?.[type]) {
        return k[item.config[type]];
      }
      return k[type];
    }
  }
};
</script>
<style lang='scss' scoped>
</style>
